<?php
/**
 * 功能：所有数据库驱动的抽象基础类
 * 说明：
 * 创建日期：2012-04-09
 * 更新日期：
 * 作者：Mirze
 * 补充说明： 
 * 
 */
abstract class db_abstract
{
	protected $_config = array();
	/** 数据库连接信息 **/
	protected $_dsn;
	/** 数据库连接句柄 **/
	protected $_conn;
	/** 查询句柄 **/
	protected $_handle = null;

	/** 最近一次插入操作或者 nextID() 操作返回的插入 ID **/
    protected $_insert_id;
    /** 指示事务启动次数 **/
    protected $_trans_count = 0;

	/** 最后一次数据库操作的错误信息 **/
    protected $_last_err;
	/** 最后一次数据库操作的错误代码 **/
    protected $_last_err_code;
	/** 指示事务执行期间是否发生了错误 **/
    protected $_has_failed_query = false;	

	/**
     * 数据库架构查询结果返回格式
     */
    // 返回的每一个记录就是一个索引数组
    const FETCH_MODE_ARRAY  = 1;
    // 返回的每一个记录就是一个以字段名作为键名的数组
    const FETCH_MODE_ASSOC  = 2;

	/** 指示返回结果集的形式 **/
    protected $_fetch_mode = self::FETCH_MODE_ASSOC;


	/** 指示是否将查询结果中的字段名转换为全小写 **/
	public $result_field_name_lower = false;

	
	public function __construct($config)
    {
	}

	/** 连接数据库，失败时抛出异常: 如果已经连接到了数据库，再次连接不会造成任何影响。 **/
    abstract function connect();

    /** 创建一个持久连接，失败时抛出异常: 如果已经连接到了数据库，再次连接不会造成任何影响。 **/
    abstract function pconnect();

   /** 强制创建一个新连接，失败时抛出异常: 如果已经连接到了数据库，再次连接不会造成任何影响。 **/
    abstract function nconnect();

    /** 关闭数据库连接 **/
    abstract function close();

	/** 获得一个名字的规范名 **/
    abstract function identifier($name);

	/**
     * (功能描述) 执行一个查询，返回一个查询对象或者 boolean 值，出错时抛出异常
     *
     * $sql 是要执行的 SQL 语句字符串，而 $inputarr 则是提供给 SQL 语句中参数占位符需要的值。
     *
     * 如果执行的查询是诸如 INSERT、DELETE、UPDATE 等不会返回结果集的操作，
     * 则 execute() 执行成功后会返回 true，失败时将抛出异常。
     *
     * 如果执行的查询是 SELECT 等会返回结果集的操作，
     * 则 execute() 执行成功后会返回一个 DBO_Result 对象，失败时将抛出异常。
     *
     * 对象封装了查询结果句柄，而不是结果集。
     * 因此要获得查询的数据，需要调用 fetchAll() 等方法。
     *
     * 如果希望执行 SQL 后直接获得结果集，可以使用驱动的 getAll()、getRow() 等方法。
     *
     * example:
     * @code
     * $sql = "INSERT INTO posts (title, body) VALUES (?, ?)";
     * $dbo->execute($sql, array($title, $body));
     * @endcode
     *
     * example:
     * @code
     * $sql = "SELECT * FROM posts WHERE post_id < 12";
     * $handle = $dbo->execute($sql);
     * $rowset = $handle->fetchAll();
     * $handle->free();
     * @endcode
     *
     * @param string $sql
     * @param array $inputarr
     * @return 
     */
	abstract function execute($sql, $inputarr = null);

	/** 从查询句柄提取一条记录 **/
	abstract function fetchRow();


	/**
	 * (功能描述) 执行一个查询并返回记录集，失败时抛出异常
     *
     * getAll() 等同于执行下面的代码：
     *
     * @code
     * $rowset = $dbo->execute($sql, $inputarr)->fetchAll();
     * @endcode
     *
     * @param string $sql
     * @param array $inputarr
     * @return array
     */
	function getAll($sql, array $inputarr = null)
    {
        return $this->execute($sql, $inputarr)->fetchAll();
    }

	/**
	 * (功能描述) 从查询句柄中提取记录集
	 *
	 * @return array
	 */
	function fetchAll()
	{
		$rowset = array();
		while (($row = $this->fetchRow())) {
			$rowset[] = $row;
		}
		return $rowset;
	}

	/**
	 * (功能描述) 确认是否已经连接到数据库
     *
     * @return boolean
     */
    function isConnected()
    {
        return is_resource($this->_conn);
    }


	/**
	 * (功能描述)获得完全限定名
     *
     * @param string $name
     * @param string $alias
     * @param string $as
     *
     * @return string
     */
    function qid($name, $alias = null, $as = null)
    {
    	$name = str_replace('`', '', $name);
        if (strpos($name, '.') === false)
        {
            $name = $this->identifier($name);
        }
        else
        {
            $arr = explode('.', $name);
            foreach ($arr as $offset => $name)
            {
                if (empty($name))
                {
                    unset($arr[$offset]);
                }
                else
                {
                    $arr[$offset] = $this->identifier($name);
                }
            }
            $name = implode('.', $arr);
        }

        if ($alias)
        {
            return "{$name} {$as} " . $this->identifier($alias);
        }
        else
        {
            return $name;
        }
    }


	/** 关闭数据库连接后清理资源 **/
    protected function _clear()
    {
        $this->_conn = null;
        $this->_last_err = null;
        $this->_last_err_code = null;
        $this->_insert_id = null;
        $this->_trans_count = 0;
    }

	/**  **/
	public function __destruct()
	{		
	}
}
?>